﻿using DDD.EFCore;
using DDD.EFCore.Shared;
using DotNetCore.CAP;
using FluentValidation;
using FluentValidation.AspNetCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using OrderModule.Application.DomianEventsHandler;
using OrderModule.Application.IntegrationEventsHandler;
using OrderModule.Infrastructure;
using OrderModule.Infrastructure.Queries;
using OrderModule.Infrastructure.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace OrderModule.Application
{
    public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddOrderModule(this IServiceCollection services, IConfiguration configuration)
        {
            Console.WriteLine("Assembly.GetCallingAssembly().FullName:{0}", Assembly.GetCallingAssembly().FullName);
            Console.WriteLine("Assembly.GetEntryAssembly().FullName:{0}", Assembly.GetEntryAssembly()?.FullName);
            Console.WriteLine("Assembly.GetExecutingAssembly().FullName:{0}", Assembly.GetExecutingAssembly().FullName);

            var moduleName = Assembly.GetExecutingAssembly().FullName?.Split(", ")[0].Split(".")[0];
            Console.WriteLine("moduleName:{0}", moduleName);
            if (moduleName != null && configuration.GetSection(moduleName).Exists())
            {
                configuration = configuration.GetSection(moduleName);
            }

            //services.AddLogging();
            services.AddAutoMapper(typeof(AutoMapperProfile));
            services.AddFluentValidationAutoValidation();
            services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());

            //services.TryAddTransient<IMediator, Mediator>();
            //services.TryAddScoped<IPublisherTransactionHandler, MySqlPublisherTransactionHandler>();

            services.AddDbContext<OrderModuleDbContext>(o => o.UseMySql(configuration.GetConnectionString("MySql")));

            services.AddMediatR(cfg =>
            {
                cfg.Lifetime = ServiceLifetime.Scoped;
                cfg.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly());
                cfg.AddOpenBehavior(typeof(OrderModuleCommandUnitOfWorkBehavior<,>));
            });
            services.AddCap(o =>
            {
                o.UseEntityFramework<OrderModuleDbContext>();
                //o.UseMySql(configuration.GetConnectionString("MySql"));
                o.UseRabbitMQ(p => configuration.GetSection("RabbitMQ").Bind(p));
                o.UseDashboard();
            });

            //TODO: 用反射注册
            services.AddScoped<OrderRepository>();
            services.AddScoped<OrderQuery>();
            services.AddTransient(typeof(GoodsDeductStockSuccessIntegrationEventHanler));
            services.AddTransient(typeof(GoodsDeductStockFailIntegrationEventHandler));


            services.AddScoped<IUnitOfWork>(p => p.GetRequiredService<OrderModuleDbContext>());
            services.AddScoped<ITransaction>(p => p.GetRequiredService<OrderModuleDbContext>());

            return services;
        }


    }
}
